package sandau.self_improvement_wall.utils;

import com.auth0.jwt.JWT;
import com.auth0.jwt.JWTCreator;
import com.auth0.jwt.algorithms.Algorithm;
import com.auth0.jwt.interfaces.Claim;
import com.auth0.jwt.interfaces.DecodedJWT;
import jakarta.servlet.http.Cookie;
import jakarta.servlet.http.HttpServletRequest;

import java.util.Calendar;
import java.util.Date;
import java.util.Map;

/** payload
 iss (issuer)：签发人
 exp (expiration time)：过期时间
 sub (subject)：主题
 aud (audience)：受众
 nbf (Not Before)：生效时间
 iat (Issued At)：签发时间
 jti (JWT ID)：编号
 */

public class JWTUtils {

    private static final String SECRET = "!Q@W#E$R^Y&U";
    //token签发者
    private static final String ISSUSRE = "EDU.SANDAU";


    public static String createAccessToken(Map<String, String> map, int expTimer) {
        //创建过期时间
        Calendar instance = Calendar.getInstance();
        Date issueDate = instance.getTime();
        instance.add(Calendar.MINUTE, expTimer);
        //创建builder对象
        return getToken(map, instance, issueDate);
    }

    private static String getToken(Map<String, String> map, Calendar instance, Date issueDate) {
        JWTCreator.Builder builder = JWT.create();
        map.forEach(builder::withClaim);
        return builder.withIssuer(ISSUSRE)
                .withIssuedAt(issueDate)
                .withExpiresAt(instance.getTime()).sign(Algorithm.HMAC256(SECRET));
    }


    public static Claim getHeaderClaim(String tokenKey, String claimName) {
        return verify(tokenKey).getHeaderClaim(claimName);
    }

    public static Claim getPayloadClaim(String tokenKey, String claimName) {
        return verify(tokenKey).getClaim(claimName);
    }

    public static Map<String, Claim> getAllPayloadClaim(String tokenKey) {
        return verify(tokenKey).getClaims();
    }

    public static String createRefreshToken(Map<String, String> map, int expTimer) {
        //创建过期时间
        Calendar instance = Calendar.getInstance();
        Date issueDate = instance.getTime();
        instance.add(Calendar.DATE, expTimer);  //30天过期
        //创建builder对象
        return getToken(map, instance, issueDate);
    }


    public static DecodedJWT verify(String token) {
        return JWT.require(Algorithm.HMAC256(SECRET)).build().verify(token);
    }

    public static String getAccessToken(HttpServletRequest request){
        String accessToken = "";
        Cookie[] cookies = request.getCookies();
        if(cookies != null){
            for (Cookie cookie : cookies) {
                if (cookie.getName().equals("accessToken")) {
                    accessToken = cookie.getValue();
                    break;
                }
            }
        }
        return accessToken;
    }
    public static String getAccount(HttpServletRequest request){
        String accessToken = JWTUtils.getAccessToken(request);
        String account = null;
        if(accessToken != null && !accessToken.isEmpty()) {
            Claim claim = JWTUtils.getPayloadClaim(accessToken, "Account");
            if (claim != null) {
                account = claim.asString();
            }
        }
        return account;
    }

    public static String getAccount(String refreshToken){
        String account = null;
        if(refreshToken != null && !refreshToken.isEmpty()) {
            Claim claim = JWTUtils.getPayloadClaim(refreshToken, "Account");
            if (claim != null) {
                account = claim.asString();
            }
        }
        return account;
    }

    public static Integer getAccountId(String refreshToken){
        String accountId = null;
        Integer accId = null;
        if(refreshToken != null && !refreshToken.isEmpty()) {
            Claim claim = JWTUtils.getPayloadClaim(refreshToken, "AccountId");
            if (claim != null) {
                try{
                    accountId = claim.asString();
                }catch (Exception e){
                    e.printStackTrace();
                }
            }
            try{
                if(null != accountId) {
                    accId = Integer.parseInt(accountId);
                }
            }catch (Exception e){
                return null;
            }
        }
        return accId;
    }


    public static String getAccountWithoutVerify(HttpServletRequest request){
        String accessToken = JWTUtils.getAccessToken(request);
        String account = null;
        if(accessToken != null && !accessToken.isEmpty()) {
            DecodedJWT decodedJWT = JWT.decode(accessToken);
            Claim claim = decodedJWT.getClaim("Account");
            if (claim != null) {
                account = claim.asString();
            }
        }
        return account;
    }

    public static Integer getAccountId(HttpServletRequest request){
        String accessToken = JWTUtils.getAccessToken(request);
        String account = null;
        if(accessToken != null && !accessToken.isEmpty()) {
            Claim claim = JWTUtils.getPayloadClaim(accessToken, "AccountId");
            if (claim != null) {
                account = claim.asString();
            }
        }
        int rs = -1;
        try{
            if(null != account){
                rs = Integer.parseInt(account);
            }
        }catch (Exception e) {
            e.printStackTrace();
        }
        return rs;
    }
}

